Format codes specify either how data should be transferred or how input/output is handled.
The syntax of an IDL format code is:
[n]FC[+][-][width]
Where:
n |
is an optional repeat count (1 ≤ n) specifying the number of times the format code should be processed. If n is not specified, a repeat count of one is used. |
FC |
is the format code. See Available Format Codes, below. |
+ |
is an optional flag that specifies that positive numbers should be output with a “+” prefix. The “+” flag is only valid for numeric format codes. Normally, negative numbers are output with a “-” prefix and positive numbers have no sign prefix. Non-decimal numeric codes (B, O, and Z) allow the specification of the “+” flag, but ignore it. |
- |
is an optional flag that specifies that string or numeric values should be output with the text left-justified. Normally, output is right-justified. |
width |
is an optional width specification. Width specifications and default values are format-code specific, and are described in detail along with the format code. See Padding and Natural Width Formatting, below, for additional information on how output values are formatted based on the width parameter. |
The value being formatted may be shorter than the output width specified by the width parameter. When this happens, IDL will adjust either the contents of the output value or the width of the field, using the following mechanisms:
By default, if the value being formatted uses fewer characters than specified by the width parameter, IDL pads the value with whitespace characters on the left to create a string of the specified width. For example, the following IDL statement
PRINT, FORMAT='(I12)', 300
produces the following output:
bbbbbbbbb300
where b represents a space character.
For numeric format codes, if the first digit of the width parameter is a zero, IDL will pad the value with zeroes rather than blanks. For example:
PRINT, FORMAT='(I08)', 300
produces the following output:
00000300
When padding values with zeroes, note the following:
If the numeral zero is specified for the width parameter, IDL uses the “natural” width for the value. The value is read or output using a default format without any leading or trailing whitespace, in the style of the standard C library printf() function.
Using a value of zero for the width parameter is useful when reading tables of data in which individual elements may be of varying lengths. For example, if your data reside in tables of the following form:
26.01 92.555 344.2
101.0 6.123 99.845
23.723 200.02 141.93
Setting the format to:
FORMAT = '(3F0)'
ensures that the correct number of digits are read or output for each element.
IDL supports the following format codes:
Format Code |
Description |
Transfers character values |
|
Terminates processing |
|
Suppresses newlines in output |
|
Transfer floating-point values |
|
Transfer integer values |
|
Returns the number of characters that remain to be transferred during a read operation |
|
Output string values directly |
|
Specifies the absolute position within a record |
|
Moves the position with a record to the left |
|
Move the position within a record to the right |
|
Transfers calendar data |
|
Provides an alternative syntax for specifying the format of an output string |
For examples using different format codes, see:
The A format code transfers character data.
The syntax is:
[n]A[-][w]
where the parameters “n” and “-” are as described in Syntax of Format Codes and the width specification is as follows:
w |
is an optional width (0 ≤ w) specifying the number of characters to be transferred. If w is not specified, the entire string is transferred. On output, if w is greater than the length of the string, the string is right justified. On input, IDL strings have dynamic length, so w specifies the resulting length of input string variables. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
For example, the IDL statement,
PRINT, FORMAT = '(A6)', '123456789'
generates the following output:
123456
The colon format code terminates format processing if there are no more data remaining in the argument list.
The syntax is:
:
For example, the IDL statement,
PRINT, FORMAT = '(6(I1, :, ", "))', INDGEN(6)
will output the following comma-separated list of integer values:
0, 1, 2, 3, 4, 5
The use of the colon format code prevented a comma from being output following the final item in the argument list.
When IDL completes output format processing, it normally outputs a newline to terminate the output operation. However, if a “$” format code is found in the format specification, this default newline is not output. The “$” format code is only used on output; it is ignored during input formatting.
The syntax is:
$
One use for the “$” format code is in prompting for user input in programs that run in a tty rather than in the graphical IDL Workbench. For example, the following simple program show the difference between strings formatted with and without the “$” format code. The first PRINT statement prompts the user for input without forcing the user’s response to appear on a separate line from the prompt; the second PRINT statement makes the user enter the response on a separate line.
IDL> .run
- PRO format_test
- name=''
- age=0
- PRINT, FORMAT='($, "Enter name")'
- READ, name
- PRINT, FORMAT='("Enter age")'
- READ, age
- PRINT, FORMAT='("You are ", I0, " years old, ", A0)', age, name
- END
% Compiled module: FORMAT_TEST.
Running the procedure looks like this:
IDL> format_test
Enter name: Pat
Enter age
: 29
You are 29 years old, Pat
IDL>
where the values in italics were entered by the user in response to the prompts.
The F, D, E, and G format codes are used to transfer floating-point values between memory and the specified file.
The syntax is:
[n]F[+][-][w][.d]
[n]D[+][-][w][.d]
[n]E[+][-][w][.d][Ee]
[n]G[+][-][w][.d][Ee]
where the parameters “n”, “+”, and “-” are as described in Syntax of Format Codes and the width specification is as follows:
w |
is an optional width specification (0 ≤ w ≤ 255). The variable w specifies the number of digits to be transferred. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
d |
is an optional width specification (1 ≤ d < w). For the F, D, and E format codes, d specifies the number of positions after the decimal point. For the G format code, d specifies the number of significant digits displayed. |
e |
is an optional width (1 ≤ e ≤ 255) specifying the width of exponent part of the field. IDL ignores this value—it is allowed for compatibility with FORTRAN. |
On input, the F, D, E, and G format codes all transfer w characters from the external field and assign them as a real value to the corresponding input/output argument list datum.
The F and D format codes are used to output values using fixed-point notation. The value is rounded to d decimal positions and right-justified into an external field that is w characters wide. The value of w must be large enough to include a minus sign when necessary, at least one digit to the left of the decimal point, the decimal point, and d digits to the right of the decimal point. The code D is identical to F (except for its default values for w and d) and exists in IDL primarily for compatibility with FORTRAN.
The E format code is used for scientific (exponential) notation. The value is rounded to d decimal positions and right-justified into an external field that is w characters wide. The value of w must be large enough to include a minus sign when necessary, at least one digit to the left of the decimal point, the decimal point, d digits to the right of the decimal point, a plus or minus sign for the exponent, the character “e” or “E”, and at least two characters for the exponent.
Note: IDL uses the standard C library function snprintf() to format numbers and their exponents. As a result, different platforms may print different numbers of exponent digits.
The G format code uses the F output style when reasonable and E for other values, but displays exactly d significant digits rather than d digits following the decimal point.
On output, if the field provided is not wide enough, it is filled with asterisks (*) to indicate the overflow condition.
If w, d, or e are omitted, the values specified in the following table are used.
Data Type |
w |
d |
e |
Float, Complex |
15 |
7 |
2 (3 for Windows) |
Double |
25 |
16 |
2 (3 for Windows) |
All Other Types |
25 |
16 |
2 (3 for Windows) |
The following table shows the results of the application of various format codes to given data values. Note that normally, the case of the format code is ignored by IDL. However, the case of the E and G format codes determines the case used to output the exponent in scientific notation.
Format |
Internal Value |
Formatted Output |
F |
100.0 |
bbbb100.0000000 |
F |
100.0D |
bbbbb100.0000000000000000 |
F10.0 |
100.0 |
bbbbbb100. |
F10.1 |
100.0 |
bbbbb100.0 |
F10.4 |
100.0 |
bb100.0000 |
F2.1 |
100.0 |
** |
e11.4 |
100.0 |
b1.0000e+02 1.0000e+002 (Windows) Note that “e10.4” displays “**********” under Windows because the extra “0” added after the “e” makes the string longer than 10 characters. |
E11.4 |
100.0 |
b1.0000E+02 1.0000E+002 (Windows) |
g10.4 |
100.0 |
bbbbb100.0 |
g10.4 |
10000000.0 |
b1.000e+07 1.000e+007 (Windows) |
G10.4 |
10000000.0 |
b1.000E+07 1.000E+007 (Windows) |
The B, I, O, and Z format codes are used to transfer integer values to and from the specified file. The B format code is used to output binary values, I is used for decimal values, O is used for octal values, and Z is used for hexadecimal values.
The syntax is:
[n]B[-][w][.m]
[n]I[+][-][w][.m]
[n]O[-][w][.m]
[n]Z[-][w][.m]
where the parameters “n”, “+”, and “-” are as described in Syntax of Format Codes and the width specification is as follows:
w |
is an optional width specification (0 ≤ w ≤ 255). The variable w specifies the number of digits to be transferred. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
On output, if the field provided is not wide enough, it is filled with asterisks (*) to indicate the overflow condition.
The default values used by the I, O, and Z format codes if w is omitted are specified in the following table:
Data Type |
w |
Byte, Int, UInt |
7 |
Long, ULong, Float |
12 |
Long64, ULong64 |
22 |
Double |
23 |
All Other Types |
12 |
The default values used by the B format code if w is omitted are specified in the following table:
Data Type |
w |
Byte |
8 |
Int, UInt |
16 |
Long, ULong |
32 |
Long64, ULong64 |
64 |
All Other Types |
32 |
The following table shows the results of the application of various format codes to given data values. Note that normally, the case of the format code is ignored by IDL. However, the case of the Z format codes determines the case used to output the hexadecimal digits A-F.
Format |
Internal Value |
Formatted Output |
B |
3000 |
bbbb101110111000 |
B15 |
3000 |
bbb101110111000 |
B14.14 |
3000 |
00101110111000 |
I |
3000 |
bbb3000 |
I6.5 |
3000 |
b03000 |
I5.6 |
3000 |
***** |
I2 |
3000 |
** |
O |
3000 |
bbb5670 |
O6.5 |
3000 |
b05670 |
O5.6 |
3000 |
***** |
O2 |
3000 |
** |
z |
3000 |
bbbbbb8 |
Z |
3000 |
bbbbBB8 |
Z6.5 |
3000 |
b00BB8 |
Z5.6 |
3000 |
***** |
Z2 |
3000 |
** |
The Q format code returns the number of characters in the input record remaining to be transferred during the current read operation. It is ignored during output formatting.
The syntax is:
q
Format Q is useful for determining how many characters have been read on a line. For example, the following IDL statements count the number of characters in file demo.dat:
;Open file for reading.
OPENR, 1, "demo.dat"
;Create a longword integer to keep the count.
N = 0L
;Count the characters.
WHILE(~ EOF(1)) DO BEGIN
READF, 1, CUR, FORMAT = '(q)' & N = N + CUR
ENDWHILE
;Report the result.
PRINT, FORMAT = '("counted", N, "characters.")'
;Close file.
CLOSE, 1
On output, any quoted strings or Hollerith constants are sent directly to the output. On input, they are ignored.
The syntax for a quoted string is:
"string" or 'string'
where string is the string to be output.
Note: Quoted strings must be enclosed in either single or double quotation marks; use the type of quotation mark that is not used to enclose the entire format string.
For example, the IDL statement,
PRINT, FORMAT = '("Value: ", I0)', 23
results in the following output:
Value: 23
Note that it would have been equally correct to use double quotes around the entire format string and single quotes around the quoted string “Value: ”.
Another way to specify a quoted string is with a Hollerith constant.
The syntax for a Hollerith constant is:
nHc1c2 c3... cn
where
n |
is the number of characters in the constant (1 ≤ n ≤ 255). |
ci |
is the characters that make up the constant. The number of characters must agree with the value provided for n. |
For example, the following IDL statement,
PRINT, FORMAT = '(7HValue: , I0)', 23
results in the following output:
Value: 23
See C printf-Style Quoted String Format Code for an alternate form of the Quoted String Format Code that supports C printf-style capabilities.
The T format code specifies the absolute position in the current record.
The syntax is:
Tn
where
n |
is the absolute character position within the record to which the current position should be set (1 ≤ n). |
The T format code differs from the TL, TR, and X format codes primarily in that it specifies an absolute position rather than an offset from the current position. For example,
PRINT, FORMAT = '("First", 20X, "Last", T10, "Middle")'
produces the following output:
FirstbbbbMiddlebbbbbbbbbbLast
where “b” represents a blank space.
The TL format code moves the current position in the external record to the left.
The syntax is:
TLn
where
n |
is the number of characters to move left from the current position (1 ≤ n). If the value of n is greater than the current position, the current position is moved to column one. |
The TL format code is used to move backwards in the current record. It can be used on input to read the same data twice or on output to position the output nonsequentially. For example,
PRINT, FORMAT = '("First", 20X, "Last", TL15, "Middle")'
produces the following output:
FirstbbbbbbbbbMiddlebbbbbLast
where “b” represents a blank space.
The TR and X format codes move the current position in the record to the right.
The syntax is:
TRn
nX
where
n |
is the number of characters to skip (1 ≤ n). On input, n characters in the current input record will be passed over. On output, the current output position is moved n characters to the right. |
The TR or X format codes can be used to leave whitespace in the output or to skip over unwanted data in the input. For example, either
PRINT, FORMAT = '("First", 15X, "Last")'
or
PRINT, FORMAT = '("First", TR15, "Last")'
results in the following output:
FirstbbbbbbbbbbbbbbbLast
where “b” represents a blank space.
These two format codes differ in one way. Using the X format code at the end of an output record will not cause any characters to be written unless it is followed by another format code that causes characters to be output. The TR format code always writes characters in this situation. Thus,
PRINT, FORMAT = '("First", 15X)'
results in the following output:
First
whereas
PRINT, FORMAT = '("First", TR15)'
results in the following output:
Firstbbbbbbbbbbbbbbb
where “b” represents a blank space. The X code does not cause the blanks to be output unless there is additional output following the blanks.
The C() format code is used to transfer calendar (Julian date and/or time) data.
The syntax is:
[n]C([c0,c1,...,cx])
where the parameter “n” is as described in Syntax of Format Codes and:
ci |
represents optional calendar format subcodes, or any of the standard format codes that are allowed within a calendar specification, as described below |
If no ciare provided, the data will be transferred using the standard 24-character system format that includes the day, date, time, and year, as shown in this string:
Thu Aug 13 12:01:32 1979
For input, this default is equivalent to:
C(CDwA, X, CMoA, X, CDI, X, CHI, X, CMI, X, CSI, CYI5)
For output, this default is equivalent to:
C(CDwA, X, CMoA, X, CDI2.2, X, CHI2.2, ":", CMI2.2, ":", CSI2.2, CYI5)
Note: The C() format code represents an atomic data transfer. Nesting within the parentheses is not allowed.
Note: For input using the calendar format codes, a small offset is added to each Julian date to eliminate roundoff errors when calculating the day fraction from hours, minutes, and seconds. This offset is given by the larger of EPS and EPS*Julian, where Julian is the integer portion of the Julian date, and EPS is the EPS field from MACHAR. For typical Julian dates, this offset is approximately 6x10–10 (which corresponds to 5x10–5 seconds). This offset ensures that if the Julian date is converted back to hour, minute, and second, then the hour, minute, and second will have the same integer values as were originally input.
Note: Calendar dates must be in the range 1 Jan 4716 B.C.E. to 31 Dec 5000000, which corresponds to Julian values -1095 and 1827933925, respectively.
The following is a list of the subcodes allowed within the parenthesis of the C() format code.
Note: The calendar format subcodes are based on the A, I, and F format codes, and share the same options. See Syntax of Format Codes for additional information on the parameters not described explicitly in this section. Note that the default values of the w and d parameters are different in the calendar format subcodes than in the base A, I, and F format codes.
The CMOA subcodes transfers the month portion of a date as a string. The format for an all upper case month string is:
CMOA[-][w]
The format for a capitalized month string is:
CMoA[-][w]
The format for an all lower case month string is:
CmoA[-][w]
where:
w |
is an optional width (0 ≤ w) specifying the number of characters of the month name to be transferred. If w is not specified, three characters will be transferred. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
Note: The case of the ‘M’ and ‘O’ of these subcodes will be ignored on input, or if the MONTHS keyword for the current routine is explicitly set.
The CMOI subcode transfers the month portion of a date as an integer. The format is as follows:
CMOI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 2. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
The CDI subcode transfers the day portion of a date as an integer. The format is:
CDI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 2. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
The CYI subcode transfers the year portion of a date as an integer. The format is as follows:
CYI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 4. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
The CHI subcodes transfer the hour portion of a date as an integer. The format for a 24-hour based integer is:
CHI[+][-][w][.m]
The format for a 12 hour based integer is:
ChI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 2. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
Note: For the ChI (12 hour format), the CAPA Subcodes may be used to specify A.M. versus P.M. For CHI (24 hour format), the CAPA subcode is ignored."
The CMI subcode transfers the minute portion of a date as an integer. The format is:
CMI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 2. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
The CSI subcode transfers the seconds portion of a date as an integer. The format is:
CSI[+][-][w][.m]
where:
w |
is an optional width (0 ≤ w ≤ 255) specifying the width of the field in characters. The default width is 2. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
m |
is an optional minimum number (1 ≤ m ≤ 255) of nonblank digits to be shown on output. The field is zero-filled on the left if necessary. If m is omitted or zero, the output is padded with blanks to achieve the specified width. Note: The m parameter is ignored if w is zero. |
The CSF subcode transfers the seconds portion of a date as a floating-point value. The format is:
CSF[+][-][w][.d]
where:
w |
is an optional width specification (0 ≤ w ≤ 255). The variable w specifies the number of characters in the external field; the default is 5. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
d |
is an optional width specification (1 ≤ d < w). The variable d specifies the number of positions after the decimal point; the default is 2. |
The value of w must be large enough to include at least one digit to the left of the decimal point, the decimal point, and d digits to the right of the decimal point. On output, if the field provided is not wide enough, it is filled with asterisks (*) to indicate the overflow condition.
The CDWA subcodes transfers the day of week portion of a data as a string. The format for an all upper case day of week string is:
CDWA[-][w]
The format for a capitalized day of week string is:
CDwA[-][w]
The format for an all lower case day of week string is:
CdwA[-][w]
where:
w |
is an optional width (0 ≤ w), specifying the number of characters of the day of week name to be transferred. If w is not specified, three characters will be transferred. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
Note: The case of the ‘D’ and ‘W’ of these subcodes will be ignored on input, or if the DAYS_OF_WEEK keyword for the current routine is explicitly set.
The CAPA subcodes transfers the A.M. or P.M. portion of a date as a string. The format for an all-uppercase A.M. or P.M. string is:
CAPA[-][w]
The format for a capitalized A.M. or P.M. string is:
CApA[-][w]
The format for an all-lowercase A.M. or P.M. string is:
CapA[-][w]
where:
w |
is an optional width (0 ≤ w), specifying the number of characters of the A.M. or P.M. string to be transferred. If w is not specified, two characters will be transferred. See Padding and Natural Width Formatting for additional details on the output width of a formatted value. |
Note: The case of the first ‘A’ and ‘P’ of these subcodes will be ignored on input, or if the AM_PM keyword for the current routine is explicitly set.
Note: The CAPA subcode is only used if the ChI (12 hour format) subcode is also being used. The CAPA subcode is ignored if the CHI (24 hour format) subcode is being used.
None of these subcodes are allowed outside of a C() format specifier. In addition to the subcodes listed above, only quoted strings, “TL”, “TR”, and “X” format codes are allowed inside of the C() format specifier.
To print the current date in the default format:
PRINT, FORMAT='(C())', SYSTIME(/JULIAN)
The printed result should look something like:
Fri Aug 14 12:34:14 1998
To print the current date as a two-digit month value followed by a slash followed by a two-digit day value:
PRINT, FORMAT='(C(CMOI,"/",CDI))',SYSTIME(/JULIAN)
The printed result should look something like:
8/14
To print the current time in hours, minutes, and floating-point seconds, all zero-filled if necessary, and separated by colons:
PRINT, $
FORMAT='(C(CHI2.2,":",CMI2.2,":",CSF05.2))',SYSTIME(/JULIAN)
The printed result should look something like:
09:59:07.00
Note that to do zero-filling for the floating-point seconds, it is necessary to specify a leading 0 in the width to the CSF format code.
IDL’s explicitly formatted specifications, which are based on those found in the FORTRAN language, are extremely powerful and capable of specifying almost any desired output. However, they require fairly verbose specifications, even in simple cases. In contrast, the C language (and the many languages influenced by C) have a different style of format specification used by functions such as printf() and snprintf(). Most programmers are very familiar with such formats. In this style, text and format codes (prefixed by a % character) are intermixed in a single string. User-supplied arguments are substituted into the format in place of the format specifiers. Although less powerful, this style of format is easier to read and write in common simple cases.
IDL supports the use of printf-style formats within format specifications, using a special variant of the Quoted String Format Code (discussed in Quoted String and H Format Codes) in which the opening quote starts with a % character (e.g. %“ or %' rather than “ or '). The presence of this % before the opening quote (with no whitespace between them) tells IDL that this is a printf-style quoted string and not a standard quoted string.
As a simple example, consider the following IDL statement that uses normal quoted string format codes:
PRINT, FORMAT='("I have ", I0, " monkeys, ", A, ".")', $
23, 'Scott'
Executing this statement yields the output:
I have 23 monkeys, Scott.
Using a printf-style quoted string format code instead, this statement could be written:
PRINT, FORMAT='(%"I have %d monkeys, %s.")', 23, 'Scott'
These two statements are completely equivalent in their action. In fact, IDL compiles both into an identical internal representation before processing them.
The printf-style quoted string format codes can be freely mixed with any other format code, so hybrid formats like the following are allowed:
PRINT, $
FORMAT='(%"I have %d monkeys, %s,", " and ", I0, " parrots.")',$
23, 'Scott', 5
This generates the output:
I have 23 monkeys, Scott, and 5 parrots.
The following table lists the % format codes allowed within a printf-style quoted string format code, as well as their correspondence to the standard format codes that do the same thing. In addition to the format codes described in the table, the special sequence %% causes a single % character to be written to the output. This % is treated as a regular character instead of as a format code specifier. Finally, the flags and the width padding options described in Syntax of Format Codes are also available when using printf-style format codes.
Printf-Style |
Normal-Style |
Normal Style Described in Section |
%[w.d]e or %[w.d]E |
e[w.d] or E[w.d] |
|
%[w]b or %[w]B %[w.m]b or %[w.m]B |
B[w] B[w.m] |
|
%[w]d or %[w]D %[w.m]D or %[w.m]D %[w]i or %[w]I %[w.m]i or %[w.m]I |
I[w] I[w.m] I[w] I[w.m] |
|
%[w]f or %[w]F %[w.d]f or %[w.d]F |
F[w] F[w.d] |
|
%[w]g or %[w]G %[w.d]g or %[w.d]G |
g[w] or G[w] g[w.d] or G[w.d] |
|
%[w]o or %[w]O %[w.m]o or %[w.m]O |
O[w] O[w.m] |
|
%[w]s or %[w]S |
A[w] |
|
%[w]x or %[w]X %[w.m]x or %[w.m]X %[w]z or %[w]Z %[w.m]z or %[w.m]Z |
Z[w] Z[w.m] Z[w] Z[w.m] |
|
As indicated in the above table, there is a one to one correspondence between each printf-style % format code and one of the normal format codes documented earlier in this chapter. When reading this table, please keep the following considerations in mind:
E[w.dEe] or e[w.dEe]
G[w.dEe] or g[w.dEe]
These styles are not available using the printf-style format codes. In other words, the following formats are not allowed:
%[w.dEe]E or %[w.dEe]e
%[w.dEe]G or %[w.dEe]g
The C programming language allows “escape sequences” that start with the backslash character, \, to appear within strings. These escapes are used in several ways:
print, format='(%"I have \xb1%d monkeys")', 5
results in the following output:
I have ±5 monkeys
Although IDL does not normally support backslash escapes within strings, the escapes described in the following table are allowed within printf-style quoted string format codes. If a character not specified in this table is preceded by a backslash, the backslash is removed and the character is inserted into the output without any special interpretation. This means that \" puts a single " character into the output and that " does not terminate the string constant. Another useful example is that \% causes a single % character to be placed into the output without starting a format code. Hence, \% and %% mean the same thing: a single % character with no special meaning.
Escape Sequence |
ASCII code |
\a |
BEL (7B) |
\b |
Backspace (8B) |
\f |
Formfeed (12B) |
\n |
Linefeed (10B) |
\r |
Carriage Return (13B) |
\t |
Horizontal Tab (9B) |
\v |
Vertical Tab (11B) |
\ooo |
Octal value ooo (Octal value of 1-3 digits) |
\xhh |
Hexadecimal value hh (Hex value of 1-2 digits) |
Note: Case is ignored in escape sequences: either “\n” or “\N” specifies a linefeed character.
IDL’s printf-style quoted string format code is very similar to a simplified C language printf() format string. However, there are important differences that an experienced C programmer should be aware of:
IDL explicitly formatted input/output has the power and flexibility to handle almost any kind of formatted data. A common use of explicitly formatted input/output involves reading and writing tables of data. Consider a data file containing employee data records. Each employee has a name (String, 32 columns) and the number of years they have been employed (Integer, 3 columns) on the first line. The next two lines contain each employee’s monthly salary for the last twelve months. A sample file named employee.dat with this format might look like the following:
Bullwinkle 10
1000.0 9000.97 1100.0 2000.0
5000.0 3000.0 1000.12 3500.0 6000.0 900.0
Boris 11
400.0 500.0 1300.10 350.0 745.0 3000.0
200.0 100.0 100.0 50.0 60.0 0.25
Natasha 10
950.0 1050.0 1350.0 410.0 797.0 200.36
2600.0 2000.0 1500.0 2000.0 1000.0 400.0
Rocky 11
1000.0 9000.0 1100.0 0.0 0.0 2000.37
5000.0 3000.0 1000.01 3500.0 6000.0 900.12
The following IDL statements read data with the above format and produce a summary of the contents of the file:
;Open data file for input.
OPENR, 1, 'employee.dat'
;Create variables to hold the name, number of years, and monthly
;salary.
name = '' & years = 0 & salary = FLTARR(12)
;Output a heading for the summary.
PRINT, FORMAT='("Name", 28X, "Years", 4X, "Yearly Salary")'
;Note: The actual dashed line is longer than is shown here.
PRINT, '========'
;Loop over each employee.
WHILE (~ EOF(1)) DO BEGIN
;Read the data on the next employee.
READF, 1, $
FORMAT = '(A32,I3,2(/,6F10.2))', name, years, salary
;Output the employee information. Use TOTAL to sum the monthly
;salaries to get the yearly salary.
PRINT, FORMAT='(A32,I5,5X,F10.2)', name, years, TOTAL(salary)
ENDWHILE
CLOSE, 1
The output from executing these statements on employee.dat is as follows:
Name Years Yearly Salary
======================================================
Bullwinkle 10 32501.09
Boris 11 6805.35
Natasha 10 14257.36
Rocky 11 32500.50
Frequently, data are written to files with each record containing single elements of more than one array. One example might be a file consisting of observations of altitude, pressure, temperature, and velocity with each line or record containing a value for each of the four variables. Because IDL has no equivalent of the FORTRAN implied DO list, special procedures must be used to read or write this type of file.
The first approach, which is the simplest, may be used only if all of the variables have the same data type. An array is created with as many columns as there are variables and as many rows as there are elements. The data are read into this array, the array is transposed storing each variable as a row, and each row is extracted and stored into a variable which becomes a vector. For example, the FORTRAN program which writes the data and the IDL program which reads the data are as follows:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
OPEN (UNIT = 1, STATUS='NEW', FILE='TEST')
WRITE(1,'(4(1x,g15.5))')
(ALT(I),PRES(I),TEMP(I),VELO(I),I=1,100)
;Open file for input.
OPENR, 1, 'test'
;Define variable (NVARS by NOBS).
A = FLTARR(4,100)
;Read the data.
READF, 1, A
;Transpose so that columns become rows.
A = TRANSPOSE(A)
;Extract the variables.
ALT = A[*, 0]
PRES = A[*, 1]
TEMP = A[*, 2]
VELO = A[*, 3]
Note that this same example may be written without the implied DO list, writing all elements for each variable contiguously and simplifying matters considerably:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
OPEN (UNIT = 1, STATUS='NEW', FILE='TEST')
WRITE (1,'(4(1x,G15.5))') ALT,PRES,TEMP,VELO
;Define variables.
ALT = FLTARR(100)
PRES = ALT & TEMP = ALT & VELO = ALT
OPENR, 1, 'test'
READF, 1, ALT, PRES, TEMP, VELO
A different approach must be taken when the columns contain different data types or the number of lines or records are not known. This method involves defining the arrays, defining a scalar variable to contain each datum in one record, then writing a loop to read each line into the scalars, and then storing the scalar values into each array. For example, assume that a fifth variable, the name of an observer which is of string type, is added to the variable list. The FORTRAN output routine and IDL input routine are as follows:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
CHARACTER * 10 OBS(100)
OPEN (UNIT = 1, STATUS = 'NEW', FILE = 'TEST')
WRITE (1,'(4(1X,G15.5),2X,A)')
(ALT(I),PRES(I),TEMP(I),VELO(I),OBS(I),I=1,100)
;Access file. Read files containing from 1 to 200 records.
OPENR, 1, 'test'
;Define vector, make it large enough for the biggest case.
ALT = FLTARR(200)
;Define other vectors using the first.
PRES = ALT & TEMP = ALT & VELO = ALT
;Define string array.
OBS = STRARR(200)
;Define scalar string.
OBSS = ''
;Initialize counter.
I = 0
WHILE ~ EOF(1) DO BEGIN
;Read scalars.
READF, 1, $
FORMAT = '(4(1X, G15.5), 2X, A10)', $
ALTS, PRESS, TEMPS, VELOS, OBSS
;Store in each vector.
ALT[I] = ALTS & PRES[I] = PRESS & TEMP[I] = TEMPS
VELO[I] = VELOS & OBS[I] = OBSS
;Increment counter and check for too many records.
IF I LT 199 THEN I = I + 1 ELSE STOP, 'Too many records'
ENDWHILE
If desired, after the file has been read and the number of observations is known, the arrays may be truncated to the correct length using a series of statements similar to the following:
ALT = ALT[0:I-1]
The above statement represents a worst case example. Reading is greatly simplified by writing data of the same type contiguously and by knowing the size of the file. One frequently used technique is to write the number of observations into the first record so that when reading the data the size is known.
Note: It might be tempting to implement a loop in IDL which reads the data values directly into array elements, using a statement such as the following:
FOR I = 0, 99 DO READF, 1, ALT[I], PRES[I], TEMP[I], VELO[I]
This statement is incorrect. Subscripted elements (including ranges) are temporary expressions passed as values to procedures and functions (READF in this example). Parameters passed by value do not pass results back to the caller. The proper approach is to read the data into scalars and assign the values to the individual array elements as follows:
A = 0. & P = 0. & T = 0. & V = 0.
FOR I = 0, 99 DO BEGIN
READF, 1, A, P, T, V
ALT[I] = A & PRES[I] = P & TEMP[I] = T &
VELO[I] = V
ENDFOR